package com.sds.replicator.servlets;

import com.google.common.collect.Sets;
import com.sds.replicator.helpers.RequestWrapper;
import com.sds.replicator.helpers.ResponseWrapper;
import com.sds.replicator.helpers.StringUtils;
import com.sds.replicator.transformers.CSSTransformer;
import com.sds.replicator.transformers.HTMLTransformer;
import com.sds.replicator.transformers.JSTransformer;
import com.sds.replicator.transformers.Transformer;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Set;
import java.util.logging.Logger;

public abstract class FetcherServlet extends HttpServlet {

    protected Logger logger = Logger.getLogger(getClass().getName());

    protected String localPath;
    protected String targetHost;
    protected Set<Transformer> transformers = Sets.newHashSet();

    protected FetcherServlet(String localPath, String targetHost) {
        this.localPath = localPath;
        this.targetHost = targetHost;

        transformers.add(new HTMLTransformer(localPath));
        transformers.add(new CSSTransformer(localPath));
        transformers.add(new JSTransformer(localPath));
    }

    @Override
    protected void service(HttpServletRequest incomingRequest, HttpServletResponse response) throws ServletException, IOException {
        String targetURL = transformURL(incomingRequest.getParameter("url"), incomingRequest);
        logger.info("Fetching:" + targetURL);
        HttpURLConnection httpURLConnection = RequestWrapper.wrap(incomingRequest).connect(targetURL);
        ResponseWrapper.wrap(localPath, httpURLConnection).writeContent(response, getTransformer(httpURLConnection.getContentType()));
    }

    private Transformer getTransformer(String contentType) {
        for (Transformer transformer : transformers) {
            if (contentType.contains(transformer.getContentType()))
                return transformer;
        }
        return null;
    }

    protected String transformURL(String targetURL, HttpServletRequest incomingRequest) {
        targetURL = targetURL == null ? targetHost : targetURL;
        targetURL = StringUtils.decodeURL(targetURL);
        targetURL = !targetURL.trim().startsWith("http") ? targetHost + targetURL : targetURL;
        targetURL = targetURL.replace(targetHost + "/", targetHost);
        if (incomingRequest.getQueryString() != null) {
            targetURL = targetURL + incomingRequest.getQueryString().replace("url=" + incomingRequest.getParameter("url"), "");
        }
        targetURL = targetURL.replace(
                "fb-connect-vn.appspot.com",
                targetHost
                        .replace("https", "")
                        .replace("http", "")
                        .replace("://", "")
                        .replace("/", ""));
        targetURL = targetURL.replace("%2F" + localPath.substring(1), "");
        return targetURL;
    }
}
